"""
策略基类 - 所有策略必须继承此类
【精确控制】增强策略停止时的资源清理
"""
import logging
import uuid
import time
from abc import ABC, abstractmethod
from typing import Dict, Any, Optional, Set

logger = logging.getLogger("BaseStrategy")

class BaseStrategy(ABC):
    """策略基类 - 所有量化策略的父类"""
    
    def __init__(self, strategy_id: Optional[str] = None, params: Optional[Dict[str, Any]] = None):
        """
        初始化策略
        
        参数:
        - strategy_id: 策略ID，如果为None则自动生成
        - params: 策略参数字典
        """
        self.strategy_id = strategy_id or str(uuid.uuid4())[:8]
        self.params = params or {}
        self.is_running = False
        self.positions = {}  # {symbol: volume}
        self.created_at = time.time()
        self._subscribed_stocks: Set[str] = set()
        
        logger.info(f"🆕 创建策略实例: {self.__class__.__name__} / {self.strategy_id}")
    
    @abstractmethod
    async def on_init(self):
        """策略初始化 - 子类必须实现"""
        pass
    
    @abstractmethod
    async def on_tick(self, data: Dict[str, Any]):
        """
        行情处理 - 子类必须实现
        
        参数:
        - data: 行情数据，格式取决于QMT
        """
        pass
    
    @abstractmethod
    async def on_stop(self):
        """策略停止回调 - 子类必须实现"""
        pass
    
    async def start(self):
        """启动策略"""
        if self.is_running:
            logger.warning(f"🔄 策略 {self.strategy_id} 已在运行中")
            return
        
        self.is_running = True
        await self.on_init()
        logger.info(f"▶️ 策略已启动: {self.__class__.__name__} / {self.strategy_id}")
    
    async def stop(self):
        """【精确控制】停止策略 - 自动清理所有资源"""
        if not self.is_running:
            logger.warning(f"⏹️ 策略 {self.strategy_id} 未在运行中")
            return
        
        # 1. 标记为停止
        self.is_running = False
        
        # 2. 【关键优化】调用清理方法
        await self._cleanup_resources()
        
        # 3. 调用子类实现
        await self.on_stop()
        
        logger.info(f"⏹️ 策略已完全停止: {self.__class__.__name__} / {self.strategy_id}")
    



    async def _cleanup_resources(self):
        """
        【精确控制】清理策略资源 - 确保无残留
        
        优化点:
        1. 自动取消所有订阅
        2. 平仓所有持仓 (可选)
        3. 释放内存资源
        """
        from .strategy_manager import StrategyManager
        manager = StrategyManager()
        
        # 1. 取消所有订阅
        for stock_code in list(self._subscribed_stocks):
            await manager.remove_subscription(stock_code, self.strategy_id)
        self._subscribed_stocks.clear()
        
        # 2. 【可选】平仓所有持仓
        for symbol, volume in list(self.positions.items()):
            if volume != 0:
                logger.info(f"CloseOperation: 平仓 {symbol} {abs(volume)}股 (策略停止)")
                await self.sell(symbol, volume)
        
        logger.debug(f"🧹 策略资源已清理: {self.strategy_id}")
    
    async def subscribe(self, stock_code: str):
        """【增强】订阅行情 - 记录订阅列表"""
        from .strategy_manager import StrategyManager
        manager = StrategyManager()
        await manager.add_subscription(stock_code, self.strategy_id)
        
        # 记录订阅
        self._subscribed_stocks.add(stock_code)
        logger.debug(f"📝 策略 {self.strategy_id} 订阅: {stock_code}")
    


    #刷新当前系统里面默认的金额 需要有足够的钱可以买
    async def refresh_account_balance(self) -> float:
        from .qmt_client import qmt_client
        balance =qmt_client.get_account_balance()
        print(f'当前账户的余额:{balance}')
        return balance


    #刷新股票当前可卖数量
    def refresh_available_quantity_sale(self,symbol: str) -> int:
        self.positions[symbol] = self.positions.get(symbol, 0) + 10000000
        return self.positions[symbol]

    async def buy(self, symbol: str, volume: int):
        """买入操作"""
        if not self.is_running:
            logger.warning(f"⚠️ 策略 {self.strategy_id} 未运行，无法执行买入")
            return
        
        from .qmt_client import qmt_client
		
        # 执行买入
        order_id = qmt_client.order_stock(symbol, volume)
        self.positions[symbol] = self.positions.get(symbol, 0) + volume
        
        logger.info(f"📈 策略 {self.strategy_id} 买入: {symbol} {volume}股 (订单ID: {order_id})")
        return order_id
    
    async def sell(self, symbol: str, volume: int):
        """卖出操作 (支持正数)"""
        if not self.is_running:
            logger.warning(f"⚠️ 策略 {self.strategy_id} 未运行，无法执行卖出")
            return
        
        from .qmt_client import qmt_client
        
        # 确保volume为正数
        volume = abs(volume)
        
        # 检查是否有足够持仓
        current_volume = self.positions.get(symbol, 0)
        if current_volume < volume:
            logger.warning(f"⚠️ 策略 {self.strategy_id} {symbol} 持仓不足，当前: {current_volume}, 需要: {volume}")
            volume = current_volume
        
        if volume <= 0:
            return
        
        # 执行卖出 (负数表示卖出)
        order_id = qmt_client.order_stock(symbol, -volume)
        self.positions[symbol] = current_volume - volume
        
        # 如果持仓为0，清理记录
        if self.positions[symbol] == 0:
            del self.positions[symbol]
        
        logger.info(f"📉 策略 {self.strategy_id} 卖出: {symbol} {volume}股 (订单ID: {order_id})")
        return order_id
    
    def update_positions(self):
        """更新持仓信息"""
        from .qmt_client import qmt_client
        positions = qmt_client.get_stock_positions()
        
        # 只更新本策略关注的股票
        for symbol in self._subscribed_stocks:
            if symbol in positions:
                self.positions[symbol] = positions[symbol]["volume"]
        
        logger.debug(f"📊 策略 {self.strategy_id} 持仓更新: {self.positions}")
    
    def __repr__(self):
        return f"<{self.__class__.__name__} id={self.strategy_id} running={self.is_running}>"